<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  
  <link rel="stylesheet" href="/public/asset/bootstrap.min.css">
  <link rel="stylesheet" href="/public/asset/bootstrap-icons-141.css">
  <link rel="stylesheet" href="/public/asset/style.css">
  
  <script src="/public/asset/jquery.min.js"></script>
  <script src="/public/asset/dayjs.min.js"></script>
  <script src="/public/asset/bootstrap.bundle.min.js"></script>
  <script src="/public/asset/util.js"></script>
  
  <title>An Island in iPelago</title>
  <style>
    .bi {
      cursor: pointer;
    }
  </style>
</head>
<body>
  <div id="root" class="container" style="max-width: 775px; min-width: 400px;"></div>

<script>

const idForm = new FormData();
idForm.set('id', getUrlParam('id'));

let addrForm = new FormData();

let oldNote;
let lastTime;

const Loading = CreateLoading();
const Alerts = CreateAlerts();

const TitleArea = {
  view: () => m('div').addClass('d-flex justify-content-between align-items-center my-5').append([
    m('div').attr({id:'title'}).addClass('display-6').text('An Island in iPelago'),
    m('a').attr({href:'/public/home.html',title:'home'}).addClass('btn btn-outline-dark').append(
      m('i').addClass('bi bi-house-door')
    ),
  ]),
};

const StatusBadge = cc('span');
const UpdateBtn = cc('i');
const UpdateLoading = CreateSmallLoading();
function toggleUpdateBtn() {
  $(UpdateBtn.id).toggle();
  $(UpdateLoading.id).toggle();
}
const UnfollowBtn = cc('i');
const FollowAgainBtn = cc('i');
const DeleteBtn = cc('i');
const EditNoteBtn = cc('i');
const NoteInput = cc('input');
const NoteInputOK = cc('button');
const NoteInputGroup = cc('div', null, [
  m(NoteInput).attr({type:'text'}).addClass('form-control'),
  m(NoteInputOK).attr({type:'button'}).text('ok').addClass('btn btn-outline-primary'),
]);
const NoteText = cc('span');

const InfoCard = cc('div');

InfoCard.view = () => m('div').attr({id:InfoCard.raw_id}).addClass('card').append(
  m('div').addClass('card-body d-flex justify-content-start align-items-start').append([
    m('img').addClass('Avatar').attr({src:'/public/avatars/default.jpg',alt:'avatar'}),
    m('div').addClass('ms-3 flex-fill').append([
      m('div').addClass('Name'),
      m(EditNoteBtn).addClass('bi bi-pencil-square').attr({title:'edit note'}),
      ' ',
      m(NoteText).addClass('text-muted'),
      m(NoteInputGroup).addClass('input-group').hide(),
    ]),
  ]),
);

InfoCard.init = (island) => {

  if (island.Avatar) {
    $(InfoCard.id).find('.Avatar').attr({src:island.Avatar})
  }

  const nameElem = $(InfoCard.id).find('.Name');
  nameElem.append( m('strong').text(island.Name) );

  if (island.Status) {
    nameElem.append([
      ' ',
      m(StatusBadge),
    ]);
    changeStatus(StatusBadge.id, island.Status);
  }

  nameElem.append([
    ' ',
    m(UpdateLoading).hide(),
    m(UpdateBtn).addClass('bi bi-arrow-repeat').attr({title:'update'}).click(() => {
      toggleUpdateBtn();
      ajax({method:'POST',url:'/api/update-island',alerts:Alerts,body:idForm},
          (island) => {
            changeStatus(StatusBadge.id, island.Status);
            if (island.Status == 'alive') {
              Alerts.insert('success', '更新成功，本页会自动刷新......');
              window.setTimeout(() => { window.location.reload() }, 3000);
            } else if (island.Status == 'alive-but-no-news') {
              Alerts.insert('success', '连接成功，但没有新消息');
            } else if (island.Status == 'timeout' || island.Status == 'down') {
              Alerts.insert('danger', '连接失败');
            } else {
              Alerts.insert('danger', '状态异常。 status: ' + island.Status);
            }
          }, null, () => {
            toggleUpdateBtn();
          });
    }),
    ' ',
    m(UnfollowBtn).addClass('bi bi-person-x').attr({title:'unfollow'}).click(() => {
      ajax({method:'POST',url:'/api/unfollow',alerts:Alerts,buttonID:UnfollowBtn.id,body:idForm},
          () => {
            changeStatus(StatusBadge.id, 'unfollowed');
            toggleUnfollow();
          });
    }),
    m(FollowAgainBtn).addClass('bi bi-person-check').attr({title:'follow again'}).hide().click(() => {
      ajax({method:'POST',url:'/api/follow-again',alerts:Alerts,buttonID:FollowAgainBtn.id,body:idForm},
          () => {
            changeStatus(StatusBadge.id, 'alive');
            toggleUnfollow();
          });
    }),
    ' ',
    m(DeleteBtn).addClass('bi bi-trash').attr({title:'delete'}).hide().click(() => {
      Alerts.insert('primary', `请按 F12 进入网页控制台，输入命令 delete_island() 按回车即可删除【${island.Name}】及其全部消息。输入命令 deny_island() 可屏蔽该岛（拉黑），而输入命令 delete_and_deny() 则可同时删除及拉黑。`);
    }),
  ]);

  function toggleUnfollow() {
    $(UpdateBtn.id).toggle();
    $(UnfollowBtn.id).toggle();
    $(FollowAgainBtn.id).toggle();
    $(DeleteBtn.id).toggle();
  }

  if (island.Status == 'unfollowed') {
    toggleUnfollow();
  }

  if (island.Email) {
    nameElem.append([
      m('br'),
      m('span').addClass('small text-muted').text(island.Email),
    ]);
  }

  nameElem.append([
    m('br'),
    m('span').addClass('small text-muted').text(island.Address),
  ]);

  if (island.Link) {
    nameElem.append([
      m('br'),
      m('a').addClass('small').text(island.Link).attr({href:island.Link}),
    ]);
  }

  const noteText = $(NoteText.id);
  const noteInput = $(NoteInput.id);
  const inputGroup = $(NoteInputGroup.id);

  function toggleInput() {
    inputGroup.toggle();
    noteText.toggle();
  }

  if (island.Note) {
    noteText.text(island.Note);
    noteInput.val(island.Note);
  }

  $(EditNoteBtn.id).click(() => {
    toggleInput();
    noteInput.focus();
  });

  $(NoteInputOK.id).click(() => {
    const newNote = noteInput.val().trim();
    if (newNote == oldNote) {
      toggleInput();
      return;
    }
    const body = new FormData();
    body.set('id', island.ID);
    body.set('note', newNote);
    ajax({method:'POST',url:'/api/update-note',alerts:Alerts,buttonID:NoteInputOK.id,body:body},
        () => {
          oldNote = newNote;
          noteText.text(newNote);
          toggleInput();
        }, () => {
          noteInput.focus();
        });
  });
};

const MsgList = cc('ul');

MsgList.view = () => m('ul')
  .attr({id:MsgList.raw_id}).addClass('list-group list-group-flush');

MsgList.append = (messages) => {
  messages.forEach((msg) => {
    const item = MsgItem(msg);
    $(MsgList.id).append(m(item));
  });
};

const MoreBtn = cc('button');
const BottomAlerts = CreateAlerts();

const BottomArea = cc('p', null, [
  m(MoreBtn).text('More').addClass('btn btn-primary').attr({type:'button'}).hide(),
]);

$('#root').append([
  m(TitleArea),
  m(Loading),
  m(InfoCard).hide(),
  m(Alerts).addClass('my-3'),
  m(MsgList),
  m(BottomAlerts),
  m(BottomArea).addClass('text-center my-5').hide(),
]);

init();

function init() {
  const island_id = getUrlParam('id');

  ajax({method:'GET',url:'/api/get-island/'+island_id,alerts:Alerts},
      (island) => {
        addrForm.set('address', island.Address);
        oldNote = island.Note;
        $('title').text(`${island.Name} in iPelago`);
        $(InfoCard.id).show();
        InfoCard.init(island);
        getMessages(island_id);
      }, null, () => {
        $(Loading.id).hide();
      });
}

function getMessages(id) {
  ajax({method:'GET',url:'/api/more-island-messages?id='+id,alerts:Alerts},
      (messages) => {
        if (!messages || messages.length == 0) {
          Alerts.insert('info', '没有消息');
          return;
        }
        $(BottomArea.id).show();
        MsgList.append(messages);
        lastTime = messages[messages.length-1].Time;

        if (messages.length >= everyPage) {
          $(MoreBtn.id).show().click(() => {
            ajax({method:'GET',url:`/api/more-island-messages?id=${id}&time=${lastTime}`,alerts:BottomAlerts,buttonID:MoreBtn.id},
                (moreMessages) => {
                  if (!moreMessages || moreMessages.length == 0) {
                    BottomAlerts.insert('primary', '没有更多消息了');
                    $(MoreBtn.id).hide();
                    return;
                  }
                  MsgList.append(moreMessages);
                  lastTime = moreMessages[moreMessages.length-1].Time;
                });
          });
        }
      });
}

function itemID(id) {
  return `i${id}`;
}

function MsgItem(msg) {
  const datetime = dayjs.unix(msg.Time).format('YYYY-MM-DD HH:mm:ss');
  const ItemAlerts = CreateAlerts();
  const self = cc('div', itemID(msg.ID))

  self.view = () => m('li').attr({id:self.raw_id}).addClass('list-group-item MsgItem mb-3').append([
      m('div').addClass('Datetime small text-muted').text(datetime),
      m('span').addClass('Contents').text(msg.Body),
      m(ItemAlerts),
  ]);

  return self;
}

function delete_and_deny() {
  delete_island(true);
}

function delete_island(deny) {
  ajax({method:'POST',url:'/api/delete-island',alerts:Alerts,body:idForm},
      () => {
        $(FollowAgainBtn.id).hide();
        $(DeleteBtn.id).hide();
        $(EditNoteBtn.id).hide();
        const msg = '该岛及其全部消息已被删除。';
        Alerts.clear();
        Alerts.insert('success', msg);
        console.log(msg);
        if (deny) {
          deny_island();
        }
      });
}

function deny_island(islandAddr) {
  const showSuccess = () => {
    const msg = '该岛已被添加到黑名单。';
    Alerts.insert('success', msg);
    console.log(msg);
  };
  ajax({method:'POST',url:'/api/deny-island',alerts:Alerts,body:addrForm},
      () => {
        showSuccess();
      }, (errMsg) => {
        if (errMsg.indexOf("UNIQUE constraint failed: denylist.address") >= 0) {
          showSuccess();
        } else {
          Alerts.insert('danger', errMsg);
          console.log(errMsg);
        }
      });
}

</script>
</body>
</html>